<!DOCTYPE html>
<html lang="en">
<head>
<title>SChannel helper: SChannel.Utils</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="generator" content="PasDoc 0.16.0">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="StyleSheet" type="text/css" href="pasdoc.css">
</head>
<body>
<div class="container"><div class="navigation">
<h2><a href="index.html">SChannel helper</a></h2><ul><li><a href="AllUnits.html">Units</a></li><li><a href="ClassHierarchy.html">Class Hierarchy</a></li><li><a href="AllClasses.html">Classes, Interfaces, Objects and Records</a></li><li><a href="AllTypes.html">Types</a></li><li><a href="AllVariables.html">Variables</a></li><li><a href="AllConstants.html">Constants</a></li><li><a href="AllFunctions.html">Functions and Procedures</a></li><li><a href="AllIdentifiers.html">Identifiers</a></li></ul></div><div class="content">
<h1 class="unit">Unit SChannel.Utils</h1>
<div class="sections">
<div class="one_section"><a class="section" href="#PasDoc-Description">Description</a></div><div class="one_section">Uses</div><div class="one_section"><a class="section" href="#PasDoc-Classes">Classes, Interfaces, Objects and Records</a></div><div class="one_section"><a class="section" href="#PasDoc-FuncsProcs">Functions and Procedures</a></div><div class="one_section"><a class="section" href="#PasDoc-Types">Types</a></div><div class="one_section"><a class="section" href="#PasDoc-Constants">Constants</a></div><div class="one_section"><a class="section" href="#PasDoc-Variables">Variables</a></div></div>
<span id="PasDoc-Description"></span><h2 class="description">Description</h2>
<p>
Helper functions for easy implementation of TLS communication by means of Windows SChannel. The functions are transport-agnostic so they could be applied to any socket implementation or even other transport.

<p>Inspired by <a href="http://www.coastrd.com/c-schannel-smtp">TLS-Sample</a>

<p>Uses <a href="https://jedi-apilib.sourceforge.net">JEDI API units</a>

<p>(c) Fr0sT-Brutal

<p>License MIT</p>
<span id="PasDoc-Uses"></span><h2 class="overview">Overview</h2>
<span id="PasDoc-Classes"></span><h3 class="cio">Classes, Interfaces, Objects and Records</h3>
<table class="classestable wide_list">
<tr class="listheader">
<th class="itemname">Name</th>
<th class="itemdesc">Description</th>
</tr>
<tr class="list">
<td class="itemname">Record&nbsp;<a class="bold" href="SChannel.Utils.THandShakeData.html"><code>THandShakeData</code></a></td>
<td class="itemdesc">United state and data for TLS handshake</td>
</tr>
<tr class="list2">
<td class="itemname">Record&nbsp;<a class="bold" href="SChannel.Utils.TSessionCreds.html"><code>TSessionCreds</code></a></td>
<td class="itemdesc">Credentials related to a connection</td>
</tr>
<tr class="list">
<td class="itemname">Interface&nbsp;<a class="bold" href="SChannel.Utils.ISharedSessionCreds.html"><code>ISharedSessionCreds</code></a></td>
<td class="itemdesc">Interface with session creds for sharing between multiple sessions</td>
</tr>
<tr class="list2">
<td class="itemname">Class&nbsp;<a class="bold" href="SChannel.Utils.TDefaultDebugFnHoster.html"><code>TDefaultDebugFnHoster</code></a></td>
<td class="itemdesc">Class with stub <a class="normal" href="SChannel.Utils.TDefaultDebugFnHoster.html#Debug">debug</a> logging function that reports messages via <code>OutputDebugString</code></td>
</tr>
<tr class="list">
<td class="itemname">Class&nbsp;<a class="bold" href="SChannel.Utils.TTrustedCerts.html"><code>TTrustedCerts</code></a></td>
<td class="itemdesc">App-local storage of trusted certs.</td>
</tr>
<tr class="list2">
<td class="itemname">Record&nbsp;<a class="bold" href="SChannel.Utils.TSessionData.html"><code>TSessionData</code></a></td>
<td class="itemdesc">Data related to a session.</td>
</tr>
<tr class="list">
<td class="itemname">Class&nbsp;<a class="bold" href="SChannel.Utils.TBaseTLSOptions.html"><code>TBaseTLSOptions</code></a></td>
<td class="itemdesc">Abstract base class for shared TLS options storage</td>
</tr>
<tr class="list2">
<td class="itemname">Record&nbsp;<a class="bold" href="SChannel.Utils.TBuffer.html"><code>TBuffer</code></a></td>
<td class="itemdesc">Trivial data storage</td>
</tr>
<tr class="list">
<td class="itemname">Class&nbsp;<a class="bold" href="SChannel.Utils.ESSPIError.html"><code>ESSPIError</code></a></td>
<td class="itemdesc">Specific exception class.</td>
</tr>
</table>
<span id="PasDoc-FuncsProcs"></span><h3 class="summary">Functions and Procedures</h3>
<table class="summary wide_list">
<tr class="list">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#LoadSecurityLibrary">LoadSecurityLibrary</a></strong>;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#CreateCredentials">CreateCredentials</a></strong>(const User: string; out hCreds: CredHandle; var SchannelCred: SCHANNEL_CRED);</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#VerifyServerCertificate">VerifyServerCertificate</a></strong>(pServerCert: PCCERT_CONTEXT; const szServerName: string; dwCertFlags: DWORD);</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#GetCertContext">GetCertContext</a></strong>(const hContext: CtxtHandle): PCCERT_CONTEXT;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#Init">Init</a></strong>;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#Fin">Fin</a></strong>;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#CreateSessionCreds">CreateSessionCreds</a></strong>(var SessionCreds: <a href="SChannel.Utils.TSessionCreds.html">TSessionCreds</a>);</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#CreateSharedCreds">CreateSharedCreds</a></strong>: <a href="SChannel.Utils.ISharedSessionCreds.html">ISharedSessionCreds</a>;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#FreeSessionCreds">FreeSessionCreds</a></strong>(var SessionCreds: <a href="SChannel.Utils.TSessionCreds.html">TSessionCreds</a>);</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#FinSession">FinSession</a></strong>(var SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>);</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#Debug">Debug</a></strong>(DebugLogFn: <a href="SChannel.Utils.html#TDebugFn">TDebugFn</a>; const Msg: string);</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#DoClientHandshake">DoClientHandshake</a></strong>(var SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>; var HandShakeData: <a href="SChannel.Utils.THandShakeData.html">THandShakeData</a>; DebugLogFn: <a href="SChannel.Utils.html#TDebugFn">TDebugFn</a> = nil): SECURITY_STATUS;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#GetShutdownData">GetShutdownData</a></strong>(const SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>; const hContext: CtxtHandle; out OutBuffer: SecBuffer);</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#GetCurrentCert">GetCurrentCert</a></strong>(const hContext: CtxtHandle): TBytes;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#CheckServerCert">CheckServerCert</a></strong>(const hContext: CtxtHandle; const ServerName: string; const TrustedCerts: <a href="SChannel.Utils.TTrustedCerts.html">TTrustedCerts</a> = nil; CertCheckIgnoreFlags: <a href="SChannel.Utils.html#TCertCheckIgnoreFlags">TCertCheckIgnoreFlags</a> = []): <a href="SChannel.Utils.html#TCertCheckResult">TCertCheckResult</a>; overload;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#CheckServerCert">CheckServerCert</a></strong>(const hContext: CtxtHandle; const SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>): <a href="SChannel.Utils.html#TCertCheckResult">TCertCheckResult</a>; overload;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#DeleteContext">DeleteContext</a></strong>(var hContext: CtxtHandle);</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#InitBuffers">InitBuffers</a></strong>(const hContext: CtxtHandle; out pbIoBuffer: TBytes; out Sizes: SecPkgContext_StreamSizes);</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>procedure <strong><a href="SChannel.Utils.html#EncryptData">EncryptData</a></strong>(const hContext: CtxtHandle; const Sizes: SecPkgContext_StreamSizes; pbMessage: PByte; cbMessage: DWORD; pbIoBuffer: PByte; pbIoBufferLength: DWORD; out cbWritten: DWORD);</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#DecryptData">DecryptData</a></strong>(const hContext: CtxtHandle; const Sizes: SecPkgContext_StreamSizes; pbIoBuffer: PByte; var cbEncData: DWORD; pbDecData: PByte; cbDecDataLength: DWORD; out cbWritten: DWORD): SECURITY_STATUS;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#SecIsNullHandle">SecIsNullHandle</a></strong>(const x: SecHandle): Boolean;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#SecStatusErrStr">SecStatusErrStr</a></strong>(scRet: SECURITY_STATUS): string;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#WinVerifyTrustErrorStr">WinVerifyTrustErrorStr</a></strong>(Status: DWORD): string;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#IsWinHandshakeBug">IsWinHandshakeBug</a></strong>(scRet: SECURITY_STATUS): Boolean;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code>function <strong><a href="SChannel.Utils.html#GetSessionCredsPtr">GetSessionCredsPtr</a></strong>(const SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>): <a href="SChannel.Utils.html#PSessionCreds">PSessionCreds</a>;</code></td>
</tr>
</table>
<span id="PasDoc-Types"></span><h3 class="summary">Types</h3>
<table class="summary wide_list">
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#THandShakeStage">THandShakeStage</a></strong> = (...);</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#TChannelState">TChannelState</a></strong> = (...);</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#PSessionCreds">PSessionCreds</a></strong> = &circ;<a href="SChannel.Utils.TSessionCreds.html">TSessionCreds</a>;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#TSessionFlag">TSessionFlag</a></strong> = (...);</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#TSessionFlags">TSessionFlags</a></strong> = set of <a href="SChannel.Utils.html#TSessionFlag">TSessionFlag</a>;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#TDebugFn">TDebugFn</a></strong> = procedure (const Msg: string) of object;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#TCertCheckIgnoreFlag">TCertCheckIgnoreFlag</a></strong> = (...);</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#TCertCheckIgnoreFlags">TCertCheckIgnoreFlags</a></strong> = set of <a href="SChannel.Utils.html#TCertCheckIgnoreFlag">TCertCheckIgnoreFlag</a>;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#PSessionData">PSessionData</a></strong> = &circ;<a href="SChannel.Utils.TSessionData.html">TSessionData</a>;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#TCertCheckResult">TCertCheckResult</a></strong> = (...);</code></td>
</tr>
</table>
<span id="PasDoc-Constants"></span><h3 class="summary">Constants</h3>
<table class="summary wide_list">
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#LogPrefix">LogPrefix</a></strong> = '[SChannel]: ';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#IO_BUFFER_SIZE">IO_BUFFER_SIZE</a></strong> = $10000;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#USED_PROTOCOLS">USED_PROTOCOLS</a></strong>: DWORD = SP_PROT_TLS1_1 or SP_PROT_TLS1_2;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#USED_ALGS">USED_ALGS</a></strong>: ALG_ID = 0;</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#SSPI_FLAGS">SSPI_FLAGS</a></strong> =
    ISC_REQ_SEQUENCE_DETECT or   
    ISC_REQ_REPLAY_DETECT or     
    ISC_REQ_CONFIDENTIALITY or   
    ISC_RET_EXTENDED_ERROR or    
    ISC_REQ_ALLOCATE_MEMORY or   
    ISC_REQ_STREAM;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#CertCheckIgnoreAll">CertCheckIgnoreAll</a></strong> = [Low(<a href="SChannel.Utils.html#TCertCheckIgnoreFlag">TCertCheckIgnoreFlag</a>)..High(<a href="SChannel.Utils.html#TCertCheckIgnoreFlag">TCertCheckIgnoreFlag</a>)];</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_Received">S_Msg_Received</a></strong> = 'Received %d bytes of encrypted data / %d bytes of payload';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_SessionClosed">S_Msg_SessionClosed</a></strong> = 'Server closed the session [SEC_I_CONTEXT_EXPIRED]';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_Renegotiate">S_Msg_Renegotiate</a></strong> = 'Server requested renegotiate';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_Sending">S_Msg_Sending</a></strong> = 'Sending %d bytes of payload / %d bytes encrypted';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_StartingTLS">S_Msg_StartingTLS</a></strong> = 'Starting TLS handshake';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HShStageW1Success">S_Msg_HShStageW1Success</a></strong> = 'Handshake @W1 - %d bytes sent';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HShStageW1Incomplete">S_Msg_HShStageW1Incomplete</a></strong> = 'Handshake @W1 - ! incomplete data sent';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HShStageW1Fail">S_Msg_HShStageW1Fail</a></strong> = 'Handshake @W1 - ! error sending data ([#%d] %s)';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HShStageRFail">S_Msg_HShStageRFail</a></strong> = 'Handshake @R - ! no data received or error receiving ([#%d] %s)';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HShStageRSuccess">S_Msg_HShStageRSuccess</a></strong> = 'Handshake @R - %d bytes received';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HandshakeBug">S_Msg_HandshakeBug</a></strong> = 'Handshake bug: &quot;%s&quot;, retrying';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HShStageW2Success">S_Msg_HShStageW2Success</a></strong> = 'Handshake @W2 - %d bytes sent';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HShStageW2Incomplete">S_Msg_HShStageW2Incomplete</a></strong> = 'Handshake @W2 - ! incomplete data sent';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HShStageW2Fail">S_Msg_HShStageW2Fail</a></strong> = 'Handshake @W2 - ! error sending data ([#%d] %s)';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_HShExtraData">S_Msg_HShExtraData</a></strong> = 'Handshake: got &quot;%d&quot; bytes of extra data';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_Established">S_Msg_Established</a></strong> = 'Handshake established';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_SrvCredsAuth">S_Msg_SrvCredsAuth</a></strong> = 'Server credentials authenticated';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_CredsInited">S_Msg_CredsInited</a></strong> = 'Credentials initialized';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_AddrIsIP">S_Msg_AddrIsIP</a></strong> = 'Address &quot;%s&quot; is IP, verification by name is disabled';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_ShuttingDownTLS">S_Msg_ShuttingDownTLS</a></strong> = 'Shutting down TLS';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_SendingShutdown">S_Msg_SendingShutdown</a></strong> = 'Sending shutdown notify - %d bytes of data';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Err_ListeningNotSupported">S_Err_ListeningNotSupported</a></strong> = 'Listening is not supported with SChannel yet';</code></td>
</tr>
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_CertIsTrusted">S_Msg_CertIsTrusted</a></strong> = 'Certificate is in trusted list';</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#S_Msg_CertIsValidWithFlags">S_Msg_CertIsValidWithFlags</a></strong> = 'Certificate is valid using some ignore flags';</code></td>
</tr>
</table>
<span id="PasDoc-Variables"></span><h3 class="summary">Variables</h3>
<table class="summary wide_list">
<tr class="list">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#hMYCertStore">hMYCertStore</a></strong>: HCERTSTORE = nil;</code></td>
</tr>
<tr class="list2">
<td class="itemcode"><code><strong><a href="SChannel.Utils.html#g_pSSPI">g_pSSPI</a></strong>: PSecurityFunctionTable;</code></td>
</tr>
</table>
<h2 class="description">Description</h2>
<h3 class="detail">Functions and Procedures</h3>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="LoadSecurityLibrary"></span><code>procedure <strong>LoadSecurityLibrary</strong>;</code></td>
</tr>
<tr><td colspan="1">
<p>
Mainly for internal use </p>
<h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="CreateCredentials"></span><code>procedure <strong>CreateCredentials</strong>(const User: string; out hCreds: CredHandle; var SchannelCred: SCHANNEL_CRED);</code></td>
</tr>
<tr><td colspan="1">
<p>
Mainly for internal use.  </p>
<h6 class="description_section">Parameters</h6>
<dl class="parameters">
<dt>SchannelCred</dt>
<dd>- [?IN/OUT] If <code>SchannelCred.dwVersion</code> = <code>SCHANNEL_CRED_VERSION</code>, the parameter is considered &quot;IN/OUT&quot; and won't be modified before <code>AcquireCredentialsHandle</code> call. Otherwise the parameter is considered &quot;OUT&quot; and is init-ed with default values. Thus user can pass desired values to <code>AcquireCredentialsHandle</code> function.</dd>
</dl>
<h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="VerifyServerCertificate"></span><code>procedure <strong>VerifyServerCertificate</strong>(pServerCert: PCCERT_CONTEXT; const szServerName: string; dwCertFlags: DWORD);</code></td>
</tr>
<tr><td colspan="1">
<p>
Validate certificate. Mainly for internal use. Gets called by <code><a class="normal" href="SChannel.Utils.html#CheckServerCert">CheckServerCert</a></code>    </p>
<h6 class="description_section">Parameters</h6>
<dl class="parameters">
<dt>pServerCert</dt>
<dd>- pointer to cert context</dd>
<dt>szServerName</dt>
<dd>- host name of the server to check. Could be empty but appropriate flags must be set as well, otherwise the function will raise error</dd>
<dt>dwCertFlags</dt>
<dd>- value of <code>SSL_EXTRA_CERT_CHAIN_POLICY_PARA.fdwChecks</code> field: flags defining errors to ignore. <code>0</code> to ignore nothing</dd>
</dl>
<h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="GetCertContext"></span><code>function <strong>GetCertContext</strong>(const hContext: CtxtHandle): PCCERT_CONTEXT;</code></td>
</tr>
<tr><td colspan="1">
<p>
Retrieve server certificate. Mainly for internal use. Gets called by <code><a class="normal" href="SChannel.Utils.html#CheckServerCert">CheckServerCert</a></code>. Returned result must be freed via <code>CertFreeCertificateContext</code>.   </p>
<h6 class="description_section">Parameters</h6>
<dl class="parameters">
<dt>hContext</dt>
<dd>- current session context</dd>
</dl>
<h6 class="description_section">Returns</h6>
<p class="return">server certificate data</p><h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="Init"></span><code>procedure <strong>Init</strong>;</code></td>
</tr>
<tr><td colspan="1">
<p>
Load global stuff. Must be called before any other function called. Could be called multiple times without checks. <br> <strong>Thread-unsafe! Uses global variables</strong> </p>
<h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="Fin"></span><code>procedure <strong>Fin</strong>;</code></td>
</tr>
<tr><td colspan="1">
<p>
Dispose and nullify global stuff. Could be called multiple times without checks. <br> <strong>Thread-unsafe! Uses global variables</strong></p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="CreateSessionCreds"></span><code>procedure <strong>CreateSessionCreds</strong>(var SessionCreds: <a href="SChannel.Utils.TSessionCreds.html">TSessionCreds</a>);</code></td>
</tr>
<tr><td colspan="1">
<p>
Init session creds, return data record to be used in calling other functions. Could be called multiple times (nothing will be done on already init-ed record)  </p>
<h6 class="description_section">Parameters</h6>
<dl class="parameters">
<dt>SessionCreds</dt>
<dd>- [IN, OUT] record that receives values. On first call must be zeroed. Alternatively, user could fill <code>SessionCreds.SchannelCred</code> with desired values to tune channel properties.</dd>
</dl>
<h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="CreateSharedCreds"></span><code>function <strong>CreateSharedCreds</strong>: <a href="SChannel.Utils.ISharedSessionCreds.html">ISharedSessionCreds</a>;</code></td>
</tr>
<tr><td colspan="1">
<p>
Shared creds factory</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="FreeSessionCreds"></span><code>procedure <strong>FreeSessionCreds</strong>(var SessionCreds: <a href="SChannel.Utils.TSessionCreds.html">TSessionCreds</a>);</code></td>
</tr>
<tr><td colspan="1">
<p>
Finalize session creds</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="FinSession"></span><code>procedure <strong>FinSession</strong>(var SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>);</code></td>
</tr>
<tr><td colspan="1">
<p>
Finalize session, free credentials</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="Debug"></span><code>procedure <strong>Debug</strong>(DebugLogFn: <a href="SChannel.Utils.html#TDebugFn">TDebugFn</a>; const Msg: string);</code></td>
</tr>
<tr><td colspan="1">
<p>
Print <code>debug</code> message either with user-defined function if set or default one (<code><a class="normal" href="SChannel.Utils.TDefaultDebugFnHoster.html#Debug">TDefaultDebugFnHoster.Debug</a></code> method)</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="DoClientHandshake"></span><code>function <strong>DoClientHandshake</strong>(var SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>; var HandShakeData: <a href="SChannel.Utils.THandShakeData.html">THandShakeData</a>; DebugLogFn: <a href="SChannel.Utils.html#TDebugFn">TDebugFn</a> = nil): SECURITY_STATUS;</code></td>
</tr>
<tr><td colspan="1">
<p>
Function to prepare all necessary handshake data. No transport level actions. 

<p>Function to prepare all necessary handshake data. No transport level actions.     Function actions and returning data depending on input stage: </p>

<ul class="paragraph_spacing">
  <li><p><code>HandShakeData.Stage</code> = <a class="normal" href="SChannel.Utils.html#hssNotStarted">hssNotStarted</a>. Generate client hello. <br> <em>Output stage</em>: <a class="normal" href="SChannel.Utils.html#hssSendCliHello">hssSendCliHello</a>. <br> <em>Caller action</em>: send returned data (client hello) to server <br> <em>Input data</em>: </p>

<ul class="paragraph_spacing">
  <li><p>ServerName - host we're connecting to</p></li>
</ul>

<p> <em>Output data</em>: </p>

<ul class="paragraph_spacing">
  <li><p>hContext - handle to secure context</p></li>
  <li><p>OutBuffers - array with single item that must be finally disposed with <code>g_pSSPI.FreeContextBuffer</code></p></li>
</ul>

<p></p></li>
  <li><p><code>HandShakeData.Stage</code> = <a class="normal" href="SChannel.Utils.html#hssSendCliHello">hssSendCliHello</a>. <strong>Not</strong> handled by <code>DoClientHandshake</code> <br></p></li>
  <li><p><code>HandShakeData.Stage</code> = <a class="normal" href="SChannel.Utils.html#hssReadSrvHello">hssReadSrvHello</a>, <a class="normal" href="SChannel.Utils.html#hssReadSrvHelloNoRead">hssReadSrvHelloNoRead</a>, <a class="normal" href="SChannel.Utils.html#hssReadSrvHelloContNeed">hssReadSrvHelloContNeed</a>. Handle server hello

<p><em>Output stage</em>: <a class="normal" href="SChannel.Utils.html#hssReadSrvHello">hssReadSrvHello</a>, <a class="normal" href="SChannel.Utils.html#hssReadSrvHelloNoRead">hssReadSrvHelloNoRead</a>, <a class="normal" href="SChannel.Utils.html#hssReadSrvHelloContNeed">hssReadSrvHelloContNeed</a>, <a class="normal" href="SChannel.Utils.html#hssReadSrvHelloOK">hssReadSrvHelloOK</a>. <br> <em>Caller action</em>: </p>

<ul class="paragraph_spacing">
  <li><p><a class="normal" href="SChannel.Utils.html#hssReadSrvHello">hssReadSrvHello</a>: read data from server and call <code>DoClientHandshake</code> again</p></li>
  <li><p><a class="normal" href="SChannel.Utils.html#hssReadSrvHelloNoRead">hssReadSrvHelloNoRead</a>: call <code>DoClientHandshake</code> again without reading</p></li>
  <li><p><a class="normal" href="SChannel.Utils.html#hssReadSrvHelloContNeed">hssReadSrvHelloContNeed</a>: send token returned in <code>OutBuffers</code> and call <code>DoClientHandshake</code> again</p></li>
  <li><p><a class="normal" href="SChannel.Utils.html#hssReadSrvHelloOK">hssReadSrvHelloOK</a>: send token returned in <code>OutBuffers</code> and finish</p></li>
</ul>

<p> <em>Input data</em>: </p>

<ul class="paragraph_spacing">
  <li><p>ServerName - host we're connecting to</p></li>
  <li><p>IoBuffer - buffer with data from server</p></li>
  <li><p>cbIoBuffer - size of data in buffer</p></li>
</ul>

<p> <em>Output data</em>: </p>

<ul class="paragraph_spacing">
  <li><p>IoBuffer - buffer with unprocessed data from server</p></li>
  <li><p>cbIoBuffer - length of unprocessed data from server</p></li>
  <li><p>OutBuffers - array with single item that must be finally disposed with <code>g_pSSPI.FreeContextBuffer</code> (<a class="normal" href="SChannel.Utils.html#hssReadSrvHelloContNeed">hssReadSrvHelloContNeed</a>, <a class="normal" href="SChannel.Utils.html#hssReadSrvHelloOK">hssReadSrvHelloOK</a>)</p></li>
</ul>

<p></p></li>
  <li><p><code>HandShakeData.Stage</code> = <a class="normal" href="SChannel.Utils.html#hssReadSrvHelloOK">hssReadSrvHelloOK</a>. <strong>Not</strong> handled by <code>DoClientHandshake</code> <br></p></li>
  <li><p><code>HandShakeData.Stage</code> = <a class="normal" href="SChannel.Utils.html#hssDone">hssDone</a>. <strong>Not</strong> handled by <code>DoClientHandshake</code> <br></p></li>
</ul>

<p></p>
<h6 class="description_section">Parameters</h6>
<dl class="parameters">
<dt>SessionData</dt>
<dd>- [IN/OUT] record with session data</dd>
<dt>HandShakeData</dt>
<dd>- [IN/OUT] record with handshake data</dd>
<dt>DebugLogFn</dt>
<dd>- logging callback, could be <code>Nil</code></dd>
</dl>
<h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="GetShutdownData"></span><code>procedure <strong>GetShutdownData</strong>(const SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>; const hContext: CtxtHandle; out OutBuffer: SecBuffer);</code></td>
</tr>
<tr><td colspan="1">
<p>
Generate data to send to a server on connection shutdown </p>
<h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="GetCurrentCert"></span><code>function <strong>GetCurrentCert</strong>(const hContext: CtxtHandle): TBytes;</code></td>
</tr>
<tr><td colspan="1">
<p>
Retrieve server certificate linked to current context. More suitable for userland application than <code><a class="normal" href="SChannel.Utils.html#GetCertContext">GetCertContext</a></code>, without any SChannel-specific stuff.   </p>
<h6 class="description_section">Parameters</h6>
<dl class="parameters">
<dt>hContext</dt>
<dd>- current session context</dd>
</dl>
<h6 class="description_section">Returns</h6>
<p class="return">server certificate data</p><h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="CheckServerCert"></span><code>function <strong>CheckServerCert</strong>(const hContext: CtxtHandle; const ServerName: string; const TrustedCerts: <a href="SChannel.Utils.TTrustedCerts.html">TTrustedCerts</a> = nil; CertCheckIgnoreFlags: <a href="SChannel.Utils.html#TCertCheckIgnoreFlags">TCertCheckIgnoreFlags</a> = []): <a href="SChannel.Utils.html#TCertCheckResult">TCertCheckResult</a>; overload;</code></td>
</tr>
<tr><td colspan="1">
<p>
Check server certificate   with a certificate that contains a common name that is not valid will be ignored. (<code>SECURITY_FLAG_IGNORE_CERT_CN_INVALID</code> flag will be set calling <code>CertVerifyCertificateChainPolicy</code>)    </p>
<h6 class="description_section">Parameters</h6>
<dl class="parameters">
<dt>hContext</dt>
<dd>- current session context</dd>
<dt>ServerName</dt>
<dd>- host name of the server to check. If empty, errors associated</dd>
<dt>TrustedCerts</dt>
<dd>- list of trusted certs. If cert is in this list, it won't be checked by system</dd>
<dt>CertCheckIgnoreFlags</dt>
<dd>- set of cert aspects to ignore when checking.</dd>
</dl>
<h6 class="description_section">Returns</h6>
<p class="return">Result of cert check</p><h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="CheckServerCert"></span><code>function <strong>CheckServerCert</strong>(const hContext: CtxtHandle; const SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>): <a href="SChannel.Utils.html#TCertCheckResult">TCertCheckResult</a>; overload;</code></td>
</tr>
<tr><td colspan="1">
<p>
Check server certificate - variant using SessionData only  </p>
<h6 class="description_section">Returns</h6>
<p class="return">Result of cert check</p><h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="DeleteContext"></span><code>procedure <strong>DeleteContext</strong>(var hContext: CtxtHandle);</code></td>
</tr>
<tr><td colspan="1">
<p>
Dispose and nullify security context</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="InitBuffers"></span><code>procedure <strong>InitBuffers</strong>(const hContext: CtxtHandle; out pbIoBuffer: TBytes; out Sizes: SecPkgContext_StreamSizes);</code></td>
</tr>
<tr><td colspan="1">
<p>
Receive size values for current session and init buffer length to contain full message including header and trailer </p>
<h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="EncryptData"></span><code>procedure <strong>EncryptData</strong>(const hContext: CtxtHandle; const Sizes: SecPkgContext_StreamSizes; pbMessage: PByte; cbMessage: DWORD; pbIoBuffer: PByte; pbIoBufferLength: DWORD; out cbWritten: DWORD);</code></td>
</tr>
<tr><td colspan="1">
<p>
Encrypt data (prepare for sending to server).        </p>
<h6 class="description_section">Parameters</h6>
<dl class="parameters">
<dt>hContext</dt>
<dd>- current session context</dd>
<dt>Sizes</dt>
<dd>- current session sizes</dd>
<dt>pbMessage</dt>
<dd>- input data to encrypt</dd>
<dt>cbMessage</dt>
<dd>- length of input data</dd>
<dt>pbIoBuffer</dt>
<dd>- buffer to receive encrypted data</dd>
<dt>pbIoBufferLength</dt>
<dd>- size of buffer</dd>
<dt>cbWritten</dt>
<dd>- [OUT] size of encrypted data written to buffer</dd>
</dl>
<h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="DecryptData"></span><code>function <strong>DecryptData</strong>(const hContext: CtxtHandle; const Sizes: SecPkgContext_StreamSizes; pbIoBuffer: PByte; var cbEncData: DWORD; pbDecData: PByte; cbDecDataLength: DWORD; out cbWritten: DWORD): SECURITY_STATUS;</code></td>
</tr>
<tr><td colspan="1">
<p>
Decrypt data received from server. If input data is not processed completely, unprocessed chunk is copied to beginning of buffer. Thus subsequent call to Recv could just receive to @Buffer[DataLength]         </p>
<h6 class="description_section">Parameters</h6>
<dl class="parameters">
<dt>hContext</dt>
<dd>- current session context</dd>
<dt>Sizes</dt>
<dd>- current session sizes</dd>
<dt>pbIoBuffer</dt>
<dd>- input encrypted data to decrypt</dd>
<dt>cbEncData</dt>
<dd>- [IN/OUT] length of encrypted data in buffer. After function call it is set to amount of unprocessed data that is placed from the beginning of the buffer</dd>
<dt>pbDecData</dt>
<dd>- buffer to receive decrypted data</dd>
<dt>cbDecDataLength</dt>
<dd>- size of buffer</dd>
<dt>cbWritten</dt>
<dd>- [OUT] size of decrypted data written to buffer</dd>
</dl>
<h6 class="description_section">Returns</h6>
<p class="return"> </p>

<ul class="paragraph_spacing">
  <li><p><code>SEC_I_CONTEXT_EXPIRED</code> - server signaled end of session</p></li>
  <li><p><code>SEC_E_OK</code> - message processed fully</p></li>
  <li><p><code>SEC_E_INCOMPLETE_MESSAGE</code> - need more data</p></li>
  <li><p><code>SEC_I_RENEGOTIATE</code> - server wants to perform another handshake sequence</p></li>
</ul>

<p></p><h6 class="description_section">Exceptions raised</h6>
<dl class="exceptions_raised">
<dt><a class="normal" href="SChannel.Utils.ESSPIError.html">ESSPIError</a></dt>
<dd>on error or if Result is not one of above mentioned values</dd>
</dl>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="SecIsNullHandle"></span><code>function <strong>SecIsNullHandle</strong>(const x: SecHandle): Boolean;</code></td>
</tr>
<tr><td colspan="1">
<p>
Check if handle <code>x</code> is null (has both fields equal to zero)</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="SecStatusErrStr"></span><code>function <strong>SecStatusErrStr</strong>(scRet: SECURITY_STATUS): string;</code></td>
</tr>
<tr><td colspan="1">
<p>
Returns string representaion of given security status (locale message + constant name + numeric value)</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="WinVerifyTrustErrorStr"></span><code>function <strong>WinVerifyTrustErrorStr</strong>(Status: DWORD): string;</code></td>
</tr>
<tr><td colspan="1">
<p>
Returns string representaion of given verify trust error (locale message + constant name + numeric value)</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="IsWinHandshakeBug"></span><code>function <strong>IsWinHandshakeBug</strong>(scRet: SECURITY_STATUS): Boolean;</code></td>
</tr>
<tr><td colspan="1">
<p>
Check if status is likely a Windows TLS v1.2 handshake bug (<code>SEC_E_BUFFER_TOO_SMALL</code> or <code>SEC_E_MESSAGE_ALTERED</code> status is returned by <code>InitializeSecurityContext</code> on handshake). This function only checks if parameter is one of these two values.</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="GetSessionCredsPtr"></span><code>function <strong>GetSessionCredsPtr</strong>(const SessionData: <a href="SChannel.Utils.TSessionData.html">TSessionData</a>): <a href="SChannel.Utils.html#PSessionCreds">PSessionCreds</a>;</code></td>
</tr>
<tr><td colspan="1">
<p>
Return effective pointer to session credentials - either personal or shared</p>
</td></tr>
</table>
<h3 class="detail">Types</h3>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="THandShakeStage"></span><code><strong>THandShakeStage</strong> = (...);</code></td>
</tr>
<tr><td colspan="1">
<p>
Detect replayed messages that have been encoded by using the EncryptMessage or MakeSignature functions Encrypt messages by using the EncryptMessage function When errors occur, the remote party will be notified The security package allocates output buffers for you. When you have finished using the output buffers, free them by calling the FreeContextBuffer function Stage of handshake</p>
<h6 class="description_section">Values</h6>
<ul>
<li>
<span id="hssNotStarted">hssNotStarted</span>: Initial stage</li>
<li>
<span id="hssSendCliHello">hssSendCliHello</span>: Sending client hello</li>
<li>
<span id="hssReadSrvHello">hssReadSrvHello</span>: Reading server hello - general</li>
<li>
<span id="hssReadSrvHelloNoRead">hssReadSrvHelloNoRead</span>: Reading server hello - repeat call without reading</li>
<li>
<span id="hssReadSrvHelloContNeed">hssReadSrvHelloContNeed</span>: Reading server hello - in process, send token</li>
<li>
<span id="hssReadSrvHelloOK">hssReadSrvHelloOK</span>: Reading server hello - success, send token</li>
<li>
<span id="hssDone">hssDone</span>: Final stage</li>
</ul>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="TChannelState"></span><code><strong>TChannelState</strong> = (...);</code></td>
</tr>
<tr><td colspan="1">
<p>
State of secure channel</p>
<h6 class="description_section">Values</h6>
<ul>
<li>
<span id="chsNotStarted">chsNotStarted</span>: Initial stage</li>
<li>
<span id="chsHandshake">chsHandshake</span>: Handshaking with server</li>
<li>
<span id="chsEstablished">chsEstablished</span>: Channel established successfully</li>
<li>
<span id="chsShutdown">chsShutdown</span>: Sending shutdown signal and closing connection</li>
</ul>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="PSessionCreds"></span><code><strong>PSessionCreds</strong> = &circ;<a href="SChannel.Utils.TSessionCreds.html">TSessionCreds</a>;</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="TSessionFlag"></span><code><strong>TSessionFlag</strong> = (...);</code></td>
</tr>
<tr><td colspan="1">
<p>
Session options</p>
<h6 class="description_section">Values</h6>
<ul>
<li>
<span id="sfNoServerVerify">sfNoServerVerify</span>: If set, SChannel won't automatically verify server certificate by setting <code>ISC_REQ_MANUAL_CRED_VALIDATION</code> flag in <code>InitializeSecurityContextW</code> call. User has to call manual verification via <code><a class="normal" href="SChannel.Utils.html#CheckServerCert">CheckServerCert</a></code> after handshake is established (this allows connecting to an IP, domains with custom certs, expired certs, valid certs if system CRL is expired etc).</li>
</ul>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="TSessionFlags"></span><code><strong>TSessionFlags</strong> = set of <a href="SChannel.Utils.html#TSessionFlag">TSessionFlag</a>;</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="TDebugFn"></span><code><strong>TDebugFn</strong> = procedure (const Msg: string) of object;</code></td>
</tr>
<tr><td colspan="1">
<p>
Logging method that is used by functions to report non-critical errors and handshake details.</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="TCertCheckIgnoreFlag"></span><code><strong>TCertCheckIgnoreFlag</strong> = (...);</code></td>
</tr>
<tr><td colspan="1">
<p>
Flags to ignore some cert aspects when checking manually via <code><a class="normal" href="SChannel.Utils.html#CheckServerCert">CheckServerCert</a></code>. Mirror of <code>SECURITY_FLAG_IGNORE_*</code> constants</p>
<h6 class="description_section">Values</h6>
<ul>
<li>
<span id="ignRevokation">ignRevokation</span>: don't check cert revokation (useful if CRL is unavailable)</li>
<li>
<span id="ignUnknownCA">ignUnknownCA</span>: don't check CA</li>
<li>
<span id="ignWrongUsage">ignWrongUsage</span></li>
<li>
<span id="ignCertCNInvalid">ignCertCNInvalid</span>: don't check cert name (useful when connecting by IP)</li>
<li>
<span id="ignCertDateInvalid">ignCertDateInvalid</span>: don't check expiration date</li>
</ul>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="TCertCheckIgnoreFlags"></span><code><strong>TCertCheckIgnoreFlags</strong> = set of <a href="SChannel.Utils.html#TCertCheckIgnoreFlag">TCertCheckIgnoreFlag</a>;</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="PSessionData"></span><code><strong>PSessionData</strong> = &circ;<a href="SChannel.Utils.TSessionData.html">TSessionData</a>;</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="TCertCheckResult"></span><code><strong>TCertCheckResult</strong> = (...);</code></td>
</tr>
<tr><td colspan="1">
<p>
Result of <code><a class="normal" href="SChannel.Utils.html#CheckServerCert">CheckServerCert</a></code> function</p>
<h6 class="description_section">Values</h6>
<ul>
<li>
<span id="ccrValid">ccrValid</span>: Cert is valid</li>
<li>
<span id="ccrTrusted">ccrTrusted</span>: Cert was in trusted list, no check was performed</li>
<li>
<span id="ccrValidWithFlags">ccrValidWithFlags</span>: Cert is valid with some ignore flags</li>
</ul>
</td></tr>
</table>
<h3 class="detail">Constants</h3>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="LogPrefix"></span><code><strong>LogPrefix</strong> = '[SChannel]: ';</code></td>
</tr>
<tr><td colspan="1">
<p>
Just a suggested prefix for log output</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="IO_BUFFER_SIZE"></span><code><strong>IO_BUFFER_SIZE</strong> = $10000;</code></td>
</tr>
<tr><td colspan="1">
<p>
Size of handshake buffer</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="USED_PROTOCOLS"></span><code><strong>USED_PROTOCOLS</strong>: DWORD = SP_PROT_TLS1_1 or SP_PROT_TLS1_2;</code></td>
</tr>
<tr><td colspan="1">
<p>
Set of used protocols. Note: TLS 1.0 is not used by default, add <code>SP_PROT_TLS1_0</code> if needed</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="USED_ALGS"></span><code><strong>USED_ALGS</strong>: ALG_ID = 0;</code></td>
</tr>
<tr><td colspan="1">
<p>
Detect messages received out of sequence</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="SSPI_FLAGS"></span><code><strong>SSPI_FLAGS</strong> =
    ISC_REQ_SEQUENCE_DETECT or   
    ISC_REQ_REPLAY_DETECT or     
    ISC_REQ_CONFIDENTIALITY or   
    ISC_RET_EXTENDED_ERROR or    
    ISC_REQ_ALLOCATE_MEMORY or   
    ISC_REQ_STREAM;</code></td>
</tr>
<tr><td colspan="1">
<p>
Support a stream-oriented connection</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="CertCheckIgnoreAll"></span><code><strong>CertCheckIgnoreAll</strong> = [Low(<a href="SChannel.Utils.html#TCertCheckIgnoreFlag">TCertCheckIgnoreFlag</a>)..High(<a href="SChannel.Utils.html#TCertCheckIgnoreFlag">TCertCheckIgnoreFlag</a>)];</code></td>
</tr>
<tr><td colspan="1">
<p>
Set of cert validation ignore flags that has all items set - use it to ignore everything</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_Received"></span><code><strong>S_Msg_Received</strong> = 'Received %d bytes of encrypted data / %d bytes of payload';</code></td>
</tr>
<tr><td colspan="1">
<p>
Messages that could be written to log by various implementations. None of these are used in this unit</p>
</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_SessionClosed"></span><code><strong>S_Msg_SessionClosed</strong> = 'Server closed the session [SEC_I_CONTEXT_EXPIRED]';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_Renegotiate"></span><code><strong>S_Msg_Renegotiate</strong> = 'Server requested renegotiate';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_Sending"></span><code><strong>S_Msg_Sending</strong> = 'Sending %d bytes of payload / %d bytes encrypted';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_StartingTLS"></span><code><strong>S_Msg_StartingTLS</strong> = 'Starting TLS handshake';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HShStageW1Success"></span><code><strong>S_Msg_HShStageW1Success</strong> = 'Handshake @W1 - %d bytes sent';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HShStageW1Incomplete"></span><code><strong>S_Msg_HShStageW1Incomplete</strong> = 'Handshake @W1 - ! incomplete data sent';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HShStageW1Fail"></span><code><strong>S_Msg_HShStageW1Fail</strong> = 'Handshake @W1 - ! error sending data ([#%d] %s)';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HShStageRFail"></span><code><strong>S_Msg_HShStageRFail</strong> = 'Handshake @R - ! no data received or error receiving ([#%d] %s)';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HShStageRSuccess"></span><code><strong>S_Msg_HShStageRSuccess</strong> = 'Handshake @R - %d bytes received';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HandshakeBug"></span><code><strong>S_Msg_HandshakeBug</strong> = 'Handshake bug: &quot;%s&quot;, retrying';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HShStageW2Success"></span><code><strong>S_Msg_HShStageW2Success</strong> = 'Handshake @W2 - %d bytes sent';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HShStageW2Incomplete"></span><code><strong>S_Msg_HShStageW2Incomplete</strong> = 'Handshake @W2 - ! incomplete data sent';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HShStageW2Fail"></span><code><strong>S_Msg_HShStageW2Fail</strong> = 'Handshake @W2 - ! error sending data ([#%d] %s)';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_HShExtraData"></span><code><strong>S_Msg_HShExtraData</strong> = 'Handshake: got &quot;%d&quot; bytes of extra data';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_Established"></span><code><strong>S_Msg_Established</strong> = 'Handshake established';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_SrvCredsAuth"></span><code><strong>S_Msg_SrvCredsAuth</strong> = 'Server credentials authenticated';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_CredsInited"></span><code><strong>S_Msg_CredsInited</strong> = 'Credentials initialized';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_AddrIsIP"></span><code><strong>S_Msg_AddrIsIP</strong> = 'Address &quot;%s&quot; is IP, verification by name is disabled';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_ShuttingDownTLS"></span><code><strong>S_Msg_ShuttingDownTLS</strong> = 'Shutting down TLS';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_SendingShutdown"></span><code><strong>S_Msg_SendingShutdown</strong> = 'Sending shutdown notify - %d bytes of data';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Err_ListeningNotSupported"></span><code><strong>S_Err_ListeningNotSupported</strong> = 'Listening is not supported with SChannel yet';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_CertIsTrusted"></span><code><strong>S_Msg_CertIsTrusted</strong> = 'Certificate is in trusted list';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="S_Msg_CertIsValidWithFlags"></span><code><strong>S_Msg_CertIsValidWithFlags</strong> = 'Certificate is valid using some ignore flags';</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<h3 class="detail">Variables</h3>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="hMYCertStore"></span><code><strong>hMYCertStore</strong>: HCERTSTORE = nil;</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<table class="detail wide_list">
<tr class="list">
<td class="itemcode"><span id="g_pSSPI"></span><code><strong>g_pSSPI</strong>: PSecurityFunctionTable;</code></td>
</tr>
<tr><td colspan="1">
&nbsp;</td></tr>
</table>
<hr><span class="appinfo"><em>Generated by <a href="https://pasdoc.github.io/">PasDoc 0.16.0</a>. </em>
</span>
</div></div></body></html>
